package cn.fintecher.pangolin.service.manage.service;

import cn.fintecher.pangolin.common.exception.BadRequestException;
import cn.fintecher.pangolin.common.model.UserModel;
import cn.fintecher.pangolin.common.utils.BeanUtils;
import cn.fintecher.pangolin.common.utils.ZWDateUtil;
import cn.fintecher.pangolin.entity.elastic.SensitiveWord;
import cn.fintecher.pangolin.entity.mysql.Principal;
import cn.fintecher.pangolin.entity.mysql.QPrincipal;
import cn.fintecher.pangolin.service.manage.elastic.SensitiveWordElastic;
import cn.fintecher.pangolin.service.manage.repository.PrincipalRepository;
import cn.fintecher.pangolin.service.manage.request.AddSensitiveWordRequest;
import cn.fintecher.pangolin.service.manage.request.FindSensitiveWordRequest;
import cn.fintecher.pangolin.service.manage.request.ModifySensitiveWordRequest;
import cn.fintecher.pangolin.service.manage.response.PrincipalResponse;
import org.apache.commons.collections4.IterableUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.modelmapper.ModelMapper;
import org.modelmapper.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

/**
 * @Auther: xiaqun
 * @Description:
 * @Date: 9:37 2019/9/29
 */

@Service("sensitiveWordService")
@Transactional(rollbackFor = Exception.class)
public class SensitiveWordService {
    @Autowired
    private BaseService baseService;

    @Autowired
    private SensitiveWordElastic sensitiveWordElastic;

    @Autowired
    private PrincipalRepository principalRepository;

    @Autowired
    private ModelMapper modelMapper;

    /**
     * 查询全部敏感词
     */
    public Page<SensitiveWord> findAllSensitiveWord(FindSensitiveWordRequest request, Pageable pageable, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        BoolQueryBuilder builder = request.getBuilder();
        baseService.spliceBuilder(builder, userModel);
        SortBuilder sortBuilder = SortBuilders.fieldSort("operateTime").unmappedType("date").order(SortOrder.DESC);
        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(builder).withPageable(pageable).withSort(sortBuilder).build();
        return sensitiveWordElastic.search(searchQuery);
    }

    /**
     * 新增敏感词
     */
    public void addSensitiveWord(AddSensitiveWordRequest request, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        SensitiveWord word = new SensitiveWord();
        BeanUtils.copyPropertiesIgnoreNull(request, word);
        word.setId(UUID.randomUUID().toString().replaceAll("-", ""));
        word.setOperatorId(userModel.getId());
        word.setOperateTime(ZWDateUtil.getNowDateTime());
        sensitiveWordElastic.save(word);
    }

    /**
     * 修改敏感词
     */
    public void modifySensitiveWord(ModifySensitiveWordRequest request, String token) {
        UserModel userModel = baseService.getUserByToken(token);
        SensitiveWord sensitiveWord = sensitiveWordElastic.findById(request.getId()).orElseThrow(() -> new BadRequestException(null, "sensitiveWord", "sensitiveWord.is.null"));
        sensitiveWord.setPromptWords(request.getPromptWords());
        sensitiveWord.setSeriousWords(request.getSeriousWords());
        sensitiveWord.setOperatorId(userModel.getId());
        sensitiveWord.setOperateTime(ZWDateUtil.getNowDateTime());
        sensitiveWordElastic.save(sensitiveWord);
    }

    /**
     * 删除敏感词
     */
    public void deleteSensitiveWord(String id) {
        sensitiveWordElastic.deleteById(id);
    }

    /**
     * 查询未配置敏感词的委托方
     */
    public List<PrincipalResponse> getPrincipalNoWordConfig() {
        Iterable<SensitiveWord> iterable = sensitiveWordElastic.findAll();
        List<String> principalIds = new ArrayList<>();
        iterable.forEach(e -> principalIds.add(e.getPrincipalId()));
        Iterable<Principal> principals = principalRepository.findAll(QPrincipal.principal.id.notIn(principalIds));
        Type listType = new TypeToken<List<PrincipalResponse>>() {
        }.getType();
        return modelMapper.map(IterableUtils.toList(principals), listType);
    }
}
